package com.itheima.search;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.IOException;

public class SearchManagerTest {
    //检索索引数据

    public void testSearchIndex(Query query,int pageNum,int pageSize) throws Exception {
        //1.创建分词器Analyzer
        Analyzer analyzer = new IKAnalyzer();
        //2.创建查询对象Query
        //2.1创建查询分析器:参数1:默认查询的域,参数2:分词器
        //QueryParser queryParser = new QueryParser("bookName", analyzer);
        //2.2创建Query
//        MultiFieldQueryParser queryParser =
//                new MultiFieldQueryParser(new String[]{"bookName", "bookDesc"}, analyzer);
//        Query query = queryParser.parse("java");
        //3.创建存放索引目录Directory,指定索引存放路劲
        FSDirectory directory = FSDirectory.open(new File("D:\\com\\lucene"));
        //4.创建索引对象IndexRearch
        DirectoryReader indexReader = DirectoryReader.open(directory);
        //5.创建索引搜索对象IndexSearch,执行搜索,返回结果
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        //页号
        if(pageNum<0)pageNum = 1;
        //页大小
        //文档分页起始索引号
        int start = (pageNum-1)*pageSize;
        //文档分页结束索引号
        int end = start + pageSize;

        SortField sortField = new SortField("bookPrice", SortField.Type.FLOAT, false);
        Sort sort = new Sort(sortField);

        /**
         * 参数1:查询对象
         * 参数2:查询前N个文档
         * 返回结果:得分文档(包含文档数组,总的命中数)
         *
         */
        TopDocs topDocs = indexSearcher.search(query, end,sort);
        System.out.println("符合本次查询的总命中文档数为：" + topDocs.totalHits);

        //判断end的最大值
        if(end>topDocs.totalHits){
            end = topDocs.totalHits;
        }

        //6、处理搜索结果
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (int i = start; i < end; i++) {

            ScoreDoc scoreDoc = scoreDocs[i];
            System.out.println("文档在Lucene中的id为：" + scoreDoc.doc + "；文档分值为：" + scoreDoc.score);
            //根据lucene中的文档id查询到文档
            Document document = indexSearcher.doc(scoreDoc.doc);

            System.out.println("文档id为：" + document.get("bookId"));
            System.out.println("名称为：" + document.get("bookName"));
            System.out.println("价格为：" + document.get("bookPrice"));
            System.out.println("图片为：" + document.get("bookPic"));
            System.out.println("描述为：" + document.get("bookDesc"));
            System.out.println("---------------------------------------");
        }
        //7、释放资源
        indexReader.close();
    }

    /**
     * 使用TermQuery
     * 需求:查询图书名称域中包含有java的图书
     */
    @Test
    public void termQuery() throws Exception {
        TermQuery termQuery = new TermQuery(new Term("bookName", "java"));
        testSearchIndex(termQuery,1,2);
    }

    @Test
    public void numericRangeQuery() throws Exception {
        NumericRangeQuery<Double> query = NumericRangeQuery.newDoubleRange("bookPrice", 80d, 100d, true, true);
        testSearchIndex(query,2,2);
    }

    @Test
    public void booleanQuery() throws Exception {
        BooleanQuery query = new BooleanQuery();
        NumericRangeQuery<Double> query1 = NumericRangeQuery.newDoubleRange("bookPrice", 80d, 100d, false, false);
        query.add(query1,BooleanClause.Occur.MUST);

        TermQuery query2 = new TermQuery(new Term("bookName", "lucene"));
        query.add(query2,BooleanClause.Occur.MUST);

        testSearchIndex(query,3,4);
    }

    @Test
    public void queryParser() throws Exception {
        //1.创建分词器
        IKAnalyzer analyzer = new IKAnalyzer();
        //2.创建queryParser对象
        QueryParser queryParser = new QueryParser("bookName", analyzer);
        //3.设置查寻条件
        //含义:搜索bookName中包含java的,并且包含lucene的文档
        Query parse = queryParser.parse("bookName:java AND bookName:lucene");
        //含义:搜索bookName中包含java的,bingq包含lucene的文档
        Query parse1 = queryParser.parse("bookName:java OR bookName:lucene");
        //含义:搜索bookName中包含java的,但是不包含lucene的文档
        Query parse2 = queryParser.parse("bookName:java NOT bookName:lucene");
        testSearchIndex(parse,4,2);

    }
}
